﻿module Sustainalytics.Screening {

    export interface JQuery {
        slider(value: any): any;
        slider(option: string, property: string, newValue: any): any;
        slider(option: string, property: string): any;
    }


    var mod = angular.module(screeningToolModuleName)


    mod.directive('chart', function () {

        var baseWidth = 598;
        var baseHeight = 300;

        return {
            restrict: 'E',
            template: '<div chartslider xaxis="chartObject.xAxis" minvalue="chartObject.minValue" maxvalue="chartObject.maxValue" class="slider-container" ng-style="{ ' +
            '\'height\': returnedValue != undefined ? returnedValue.scale.endPoint : 0,' +
            '\'margin-bottom\': returnedValue != undefined ? -returnedValue.scale.endPoint : 0,' +
            '\'margin-left\': returnedValue != undefined ? returnedValue.scale.yLabelWidth + 10 : 0,' +
            '\'margin-right\': returnedValue != undefined ? returnedValue.scale.yLabelWidth + 10 : 0,' +
            '\'border\': 0} ">' +
            '</div><canvas></canvas > ',
            scope: {
                chartObject: "=value",
                returnedValue: "@"
            },
            link: function (scope, element, attrs: any) {
                var canvas = <HTMLCanvasElement>element.find('canvas')[0],
                    context = canvas.getContext('2d'),
                    chart;

                var options = {
                    type: attrs.type || "Bar",
                    width: attrs.width || baseWidth,
                    height: attrs.height || baseHeight
                };
                canvas.width = options.width;
                canvas.height = options.height;
                chart = new Chart(context);

                scope.$watch(function () { return element.attr('type'); }, function (value) {
                    if (!value) return;
                    options.type = value;
                    var chartType = options.type;
                    scope.returnedValue = chart[chartType](scope.chartObject.data, scope.chartObject.options);
                });

                //Update when charts data changes
                scope.$watch(function () { return scope.chartObject; }, function (value) {
                    if (!value) return;
                    var chartType = options.type;
                    scope.returnedValue = chart[chartType](scope.chartObject.data, scope.chartObject.options);
                });
            }
        }
    });


    mod.directive("chartslider", function () {
        return {
            restrict: 'A',
            scope: {
                xAxis: "=xaxis",
                minValue: "=minvalue",
                maxValue: "=maxvalue"
            },
            link: function (scope: any, element, attrs) {
                var closestFunction = (array: Array<number>, goal: number) => {
                    var closest = null;
                    $.each(array, function () {
                        if (closest == null || Math.abs(this - goal) < Math.abs(closest - goal)) {
                            closest = this;
                        }
                    })

                    if (closest == null)
                        return 0;

                    return closest.valueOf();
                };

                var numberWithCommas = function (number) {
                    var parts = number.toString().split(".");
                    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                    return parts.join(".");
                };


                scope.$watch(function () { return scope.xAxis; }, function (value) {
                    if (!value) return;

                    $(element)['slider']({
                        min: 0,
                        max: scope.xAxis.length - 1,
                        step: 1,
                        range: true,
                        //values: [0, scope.xAxis[scope.xAxis.length - 1]],
                        slide: function (event, ui) {
                            for (var i = 0; i < ui.values.length; ++i) {
                                if (i == 0) {
                                    scope.$apply(function () {
                                        scope.minValue = scope.xAxis[ui.values[i]];
                                    });
                                }
                                else {
                                    scope.$apply(function () {
                                        scope.maxValue = scope.xAxis[ui.values[i]];
                                    });
                                }

                                $("input.sliderValue[data-index=" + i + "]").val(numberWithCommas(scope.xAxis[ui.values[i]]));
                            }
                            $("#resolution").val(numberWithCommas(scope.xAxis[ui.values[0]])); // Fetch selected value from array
                            $(".resolution-preview").html(numberWithCommas(scope.xAxis[ui.values[0]]));
                        }
                    });
                    $("input.sliderValue").change(function () {
                        var $this = $(this);

                        if (parseInt($this.data("index")) == 0) {
                            if (parseInt($this.val()) > scope.maxValue) {
                                return;
                            }
                        }
                        else {
                            if (parseInt($this.val()) < scope.minValue) {
                                return;
                            }
                        }

                        $(element)['slider']("values", $this.data("index"), scope.xAxis.indexOf(closestFunction(scope.xAxis, parseInt($this.val()))));
                    });
                });

                scope.$watch(function () { return scope.minValue; }, function (value) {
                    if (!value) return;
                    if (!scope.xAxis) return;

                    var mValue = parseInt(value);
                    if (mValue > parseInt(scope.maxValue)) return;

                    var closestValue = closestFunction(scope.xAxis, mValue);
                    $(element)['slider']("values", "0", scope.xAxis.indexOf(closestValue));
                    //$("input.sliderValue[data-index=0]").val(closestValue);
                });

                scope.$watch(function () { return scope.maxValue; }, function (value) {
                    if (!value) return;
                    if (!scope.xAxis) return;

                    var mValue = parseInt(value);
                    if (mValue < parseInt(scope.minValue)) return;

                    var closestValue = closestFunction(scope.xAxis, mValue);
                    $(element)['slider']("values", "1", scope.xAxis.indexOf(closestValue));
                    //$("input.sliderValue[data-index=1]").val(closestValue);
                });
            }
        }
    });
}